package com.jiangyao.manager;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiangyao.common.constants.IntegralConstants;
import com.jiangyao.common.exception.ServerException;
import com.jiangyao.dao.*;
import com.jiangyao.model.entity.*;
import com.jiangyao.service.IntegralLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 积分管理器
 *
 * @author: yangyongchuan
 * @create: 2020年09月04日 23:41
 */
@Slf4j
@Component
public class IntegralManager {

	@Autowired
	private IntegralLogService integralLogService;

	@Autowired
	private IClassSubjectDao classSubjectDao;

	@Autowired
	private IClassUserDao classUserDao;

	@Autowired
	private IClassUserScoreSemesterDao classUserScoreSemesterDao;

	@Autowired
	private IUserExperienceDao userExperienceDao;

	@Autowired
	private IInterviewInvitationDao iInterviewInvitationDao;

	/**
	 * 保存积分流水日志-课堂教学完成时
	 *
	 * @param clsubIdList clsubIdList
	 */
	@Async
	public void saveIntegralLogForClassroomSubject(List<Integer> clsubIdList) {
		log.info("保存积分流水日志-课堂教学 开始");
		long startTime = System.currentTimeMillis();
		try {
			if (CollectionUtils.isEmpty(clsubIdList)) {
				throw new ServerException(100, "班级学期课程ID集合为空");
			}
			// 获取有效的课堂教学
			QueryWrapper<ClassSubject> csQW = new QueryWrapper<>();
			csQW.in("clsub_id", clsubIdList).eq("type", 1).eq("learn_status", 3).eq("status", 1);
			csQW.select("clsub_id", "org_id", "class_id");
			List<ClassSubject> classSubjectList = classSubjectDao.selectList(csQW);
			if (CollectionUtils.isEmpty(classSubjectList)) {
				throw new ServerException(100, "班级学期课程集合为空");
			}

			for (ClassSubject cs : classSubjectList) {
				// 获取组织班级成员列表
				QueryWrapper<ClassUser> cuQW = new QueryWrapper<>();
				cuQW.eq("org_id", cs.getOrgId()).eq("class_id", cs.getClassId()).eq("status", 1);
				cuQW.select("user_id");
				List<ClassUser> classUserList = classUserDao.selectList(cuQW);
				if (CollectionUtils.isEmpty(classUserList)) {
					continue;
				}
				// 为每个学员增加积分流水记录
				classUserList.forEach(cu -> {
					IntegralLog integralLog = IntegralLog.builder().userId(cu.getUserId()).sourceType(7).sourceId(cs.getClsubId().toString())
							.integralNum(IntegralConstants.INTEGRAL_NUM_CLASS_ROOM).build();
					integralLogService.saveLogAndUpdateUserIntegral(false, integralLog);
				});
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			log.info("保存积分流水日志-课堂教学 结束-总耗时：{} 毫秒", System.currentTimeMillis() - startTime);
		}
	}


	/**
	 * 保存积分流水日志-专业成绩
	 *
	 * @param classUserScoreList 业成绩集合
	 */
	@Async
	public void saveIntegralLogForClassUserScore(List<ClassUserScore> classUserScoreList) {
		log.info("保存积分流水日志-专业成绩 开始");
		long startTime = System.currentTimeMillis();
		try {
			if (CollectionUtils.isEmpty(classUserScoreList)) {
				throw new ServerException(100, "专业成绩集合为空");
			}
			// 班级成员专业学期课程ID
			List<Integer> cussIdList = classUserScoreList.stream().map(ClassUserScore::getCussId).distinct().collect(Collectors.toList());

			// 班级成员专业学期课程
			QueryWrapper<ClassUserScoreSemester> cussQW = new QueryWrapper<>();
			cussQW.in("id", cussIdList).eq("status", 1);
			cussQW.select("id", "credit");
			List<ClassUserScoreSemester> cussList = classUserScoreSemesterDao.selectList(cussQW);
			if (CollectionUtils.isEmpty(cussList)) {
				throw new ServerException(100, "班级成员专业学期课程集合为空");
			}
			// 专业学期课程与学分 map
			Map<Integer, Integer> creditMap = cussList.stream().collect(Collectors.toMap(ClassUserScoreSemester::getId, ClassUserScoreSemester::getCredit));

			for (ClassUserScore cus : classUserScoreList) {
				// 学分：1学分=1积分
				Integer credit = creditMap.get(cus.getCussId());
				credit = credit == null ? 0 : credit;
				IntegralLog integralLog = IntegralLog.builder().userId(cus.getUserId()).sourceType(8).sourceId(cus.getCussId().toString())
						.integralNum(credit).build();
				integralLogService.saveLogAndUpdateUserIntegral(false, integralLog);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			log.info("保存积分流水日志-专业成绩 结束-总耗时：{} 毫秒", System.currentTimeMillis() - startTime);
		}
	}


	/**
	 * 保存积分流水日志-个人档案
	 *
	 * @param ueIdList 个人档案ID集合
	 */
	@Async
	public void saveIntegralLogForUserExperience(List<Integer> ueIdList) {
		log.info("保存积分流水日志-个人档案 开始");
		long startTime = System.currentTimeMillis();
		try {
			if (CollectionUtils.isEmpty(ueIdList)) {
				throw new ServerException(100, "个人档案ID集合为空");
			}
			QueryWrapper<UserExperience> qw = new QueryWrapper<>();
			qw.in("id", ueIdList).eq("status", 2);
			qw.select("id", "user_id", "type");
			List<UserExperience> ueList = userExperienceDao.selectList(qw);
			if (CollectionUtils.isEmpty(ueList)) {
				throw new ServerException(100, "个人档案集合为空");
			}
			for (UserExperience ue : ueList) {
				IntegralLog integralLog = IntegralLog.builder().userId(ue.getUserId()).sourceType(ue.getType()).sourceId(ue.getId().toString())
						.integralNum(IntegralConstants.INTEGRAL_NUM_USER_EXPERIENCE).build();
				integralLogService.saveLogAndUpdateUserIntegral(false, integralLog);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			log.info("保存积分流水日志-个人档案 结束-总耗时：{} 毫秒", System.currentTimeMillis() - startTime);
		}
	}

	@Async
	public void saveIntegralLogForinterviewInvitation(InterviewInvitation interviewInvitation) {
		log.info("保存积分流水日志-获取面试邀请 开始");
		long startTime = System.currentTimeMillis();
		try {
			QueryWrapper<InterviewInvitation> qw = new QueryWrapper<>();
			qw.eq("id",interviewInvitation.getId());
			InterviewInvitation interviewInvitation1 = iInterviewInvitationDao.selectOne(qw);
			if (null == interviewInvitation1) {
				throw new ServerException(100, "面试邀请记录为空");
			}
			IntegralLog integralLog = IntegralLog.builder().userId(interviewInvitation1.getUserId()).sourceType(9).sourceId(interviewInvitation1.getId().toString())
					.integralNum(IntegralConstants.INTEGRAL_NUM_INTERVIEW).build();
			integralLogService.saveLogAndUpdateUserIntegral(false, integralLog);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			log.info("保存积分流水日志-获取面试邀请 结束-总耗时：{} 毫秒", System.currentTimeMillis() - startTime);
		}
	}

}
